package pku;

import org.omg.CORBA.TIMEOUT;

public class Utils {
    public static byte[] int2bytes(int i) {
        byte[] b = new byte[4];

        b[0] = (byte) (0xff & i);
        b[1] = (byte) ((0xff00 & i) >> 8);
        b[2] = (byte) ((0xff0000 & i) >> 16);
        b[3] = (byte) ((0xff000000 & i) >> 24);
        return b;
    }

    public static byte[] int2bytes2(int i) {
        byte[] b = new byte[2];

        b[0] = (byte) (0xff & i);
        b[1] = (byte) ((0xff00 & i) >> 8);
        return b;
    }

    public static byte[] int2bytes3(int i) {
        byte[] b = new byte[3];

        b[0] = (byte) (0xff & i);
        b[1] = (byte) ((0xff00 & i) >> 8);
        b[2] = (byte) ((0xff0000 & i) >> 16);
        return b;
    }

    public static int bytes2int(byte[] bytes) {
        int num = bytes[0] & 0xFF;
        num |= ((bytes[1] << 8) & 0xFF00);
        num |= ((bytes[2] << 16) & 0xFF0000);
        num |= ((bytes[3] << 24) & 0xFF000000);
        return num;
    }

    public static int bytes2int3(byte[] bytes) {
        int num = bytes[0] & 0xFF;
        num |= ((bytes[1] << 8) & 0xFF00);
        num |= ((bytes[2] << 16) & 0xFF0000);
        return num;
    }

    public static int bytes2int2(byte[] bytes) {
        int num = bytes[0] & 0xFF;
        num |= ((bytes[1] << 8) & 0xFF00);
        num &= 0x0000FFFF;
        return num;
    }

    public static byte[] long2bytes(long num) {
        byte[] b = new byte[8];
        for (int i = 0; i < 8; i++) {
            b[i] = (byte) (num >>> (56 - (i * 8)));
        }
        return b;
    }

    public static long bytes2long(byte[] b) {
        long temp;
        long res = 0;
        for (int i = 0; i < 8; i++) {
            res <<= 8;
            temp = b[i] & 0xff;
            res |= temp;
        }
        return res;
    }

    public static byte[] double2bytes(double d) {
        long value = Double.doubleToRawLongBits(d);
        byte[] b = new byte[8];
        for (int i = 0; i < 8; i++) {
            b[i] = (byte) ((value >> 8 * i) & 0xff);
        }
        return b;
    }

    public static double bytes2double(byte[] arr) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value |= ((long) (arr[i] & 0xff)) << (8 * i);
        }
        return Double.longBitsToDouble(value);
    }

    public static byte[] byteMergerAll(byte[]... values) {
        int length_byte = 0;
        for (byte[] value : values) {
            length_byte += value.length;
        }
        byte[] all_byte = new byte[length_byte];
        int countLength = 0;
        for (byte[] b : values) {
            System.arraycopy(b, 0, all_byte, countLength, b.length);
            countLength += b.length;
        }
        return all_byte;
    }

    public static String getKeyName(byte key) {
        switch (key) {
            case 0x00: return MessageHeader.MESSAGE_ID;
            case 0x01: return MessageHeader.TIMEOUT;
            case 0x02: return MessageHeader.PRIORITY;
            case 0x03: return MessageHeader.RELIABILITY;
            case 0x04: return MessageHeader.BORN_TIMESTAMP;
            case 0x05: return MessageHeader.STORE_TIMESTAMP;
            case 0x06: return MessageHeader.START_TIME;
            case 0x07: return MessageHeader.STOP_TIME;
            case 0x08: return MessageHeader.SHARDING_KEY;
            case 0x09: return MessageHeader.SHARDING_PARTITION;
            case 0x0a: return MessageHeader.TOPIC;
            case 0x0b: return MessageHeader.BORN_HOST;
            case 0x0c: return MessageHeader.STORE_HOST;
            case 0x0d: return MessageHeader.SEARCH_KEY;
            case 0x0e: return MessageHeader.SCHEDULE_EXPRESSION;
            case 0x0f: return MessageHeader.TRACE_ID;
        }
        return MessageHeader.MESSAGE_ID;
    }

    public static byte getByte(String headerName) {
        byte keyType;
        switch (headerName){
            //type: int
            case MessageHeader.MESSAGE_ID: keyType = 0x00; break;
            case MessageHeader.TIMEOUT: keyType = 0x01; break;
            case MessageHeader.PRIORITY: keyType = 0x02; break;
            case MessageHeader.RELIABILITY: keyType = 0x03; break;
            // type: long
            case MessageHeader.BORN_TIMESTAMP: keyType = 0x04; break;
            case MessageHeader.STORE_TIMESTAMP: keyType = 0x05; break;
            case MessageHeader.START_TIME: keyType = 0x06; break;
            case MessageHeader.STOP_TIME: keyType = 0x07; break;
            // type: double
            case MessageHeader.SHARDING_KEY: keyType = 0x08; break;
            case MessageHeader.SHARDING_PARTITION: keyType = 0x09; break;
            // type: String
            case MessageHeader.TOPIC: keyType = 0x0a;break;
            case MessageHeader.BORN_HOST: keyType = 0x0b;break;
            case MessageHeader.STORE_HOST: keyType = 0x0c;break;
            case MessageHeader.SEARCH_KEY: keyType = 0x0d;break;
            case MessageHeader.SCHEDULE_EXPRESSION: keyType = 0x0e;break;
            case MessageHeader.TRACE_ID: keyType = 0x0f;break;
            default: keyType = 0x00;
        }
        return keyType;
    }

}